package com.siwei.infoextract.wrapper.featureextract;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.siwei.infoextract.wrapper.parser.DomNode;
import com.siwei.infoextract.wrapper.parser.DomNodeIteratorCallback;
import com.siwei.infoextract.wrapper.parser.DomTreeTraversal;

public class AnnotationOutputter {

	private String outputDir;
	public AnnotationOutputter(String outputDir) {
		this.outputDir = outputDir;
	}

	private static Pattern titleAnnotationPattern = Pattern.compile("\\$title.*?\\$/title", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
	private static Pattern addressAnnotationPattern = Pattern.compile("\\$address.*?\\$/address", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
	private static Pattern phoneAnnotationPattern  = Pattern.compile("\\$phone.*?\\$/phone", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);

	public static Pattern addressPattern = Pattern.compile("([^市乡]{2,10}[市乡])??([^区县]{2,10}[区县])??[^路街]{2,10}[路街]([\\d]{1,5}号)??");
	public static Pattern phonePattern = Pattern.compile("([\\d]{1,4}-){0,2}[\\d]{5,8}");
	public static final String[] KEYWORDS = new String[]{
		"支行",
		"分行",
		"分理处",
		"店",
		"局",
	};

	public void output(DomNode domNode) throws IOException {
		File titleExs = new File(outputDir + File.separator + "title.exs");
		File addressExs = new File(outputDir + File.separator + "address.exs");
		File phoneExs = new File(outputDir + File.separator + "phone.exs");
		
		boolean titleExsExists = titleExs.exists();
		boolean addressExsExists = addressExs.exists();
		boolean phoneExsExists = phoneExs.exists();

		final FileWriter titleExsWriter = new FileWriter(titleExs, true);
		final FileWriter addressExsWriter = new FileWriter(addressExs, true);
		final FileWriter phoneExsWriter = new FileWriter(phoneExs, true);

		try {
			if (!titleExsExists) {
				titleExsWriter.write("**EXAMPLE FILE**");
				titleExsWriter.write("\r\n");
				titleExsWriter.write("\r\n");
				titleExsWriter.flush();
			}

			if (!addressExsExists) {
				addressExsWriter.write("**EXAMPLE FILE**");
				addressExsWriter.write("\r\n");
				addressExsWriter.write("\r\n");
				addressExsWriter.flush();
			}

			if (!phoneExsExists) {
				phoneExsWriter.write("**EXAMPLE FILE**");
				phoneExsWriter.write("\r\n");
				phoneExsWriter.write("\r\n");
				phoneExsWriter.flush();
			}

			final IFeatureExtrator innerTextFeature = new InnerTextFeatureExtractor();

			DomTreeTraversal traversal = new DomTreeTraversal(domNode);

			traversal.addCallback(new DomNodeIteratorCallback(){
				public void call(DomNode domNode) {					
					StringBuffer stringBuffer = new StringBuffer();

					String innerText = (String)innerTextFeature.extract(domNode);

					// append title example
					//
					Matcher matcher  = titleAnnotationPattern.matcher(innerText);
					if (matcher.find()) {
						innerText = innerText.replaceAll("\\$title", "");
						innerText = innerText.replaceAll("\\$/title", "");

						boolean isOrganizationPattern = false;
						for (int i = 0; i < KEYWORDS.length; i++) {							
							if (innerText.endsWith(KEYWORDS[i])) {
								isOrganizationPattern = true;
								break;
							}
						}

						try {
							stringBuffer.append(isOrganizationPattern);
							stringBuffer.append(" ");
							stringBuffer.append(domNode.getName());
							stringBuffer.append(" ");
							stringBuffer.append(true);
							stringBuffer.append(";");
							stringBuffer.append("\r\n");
							titleExsWriter.write(stringBuffer.toString());
						} catch (IOException ioe) {
							//skip the exception
						}

						return;
					}

					// append address example
					matcher = addressAnnotationPattern.matcher(innerText);
					if (matcher.find()) {
						innerText = innerText.trim();
						innerText = innerText.replaceAll("\\$address", "");
						innerText = innerText.replaceAll("\\$/address", "");

						boolean isAddressPattern = false;
						matcher = addressPattern.matcher(innerText);
						if (matcher.find()) {
							isAddressPattern = true;
						}
						
						
						try {
							stringBuffer.append(isAddressPattern);
							stringBuffer.append(" ");
							stringBuffer.append(domNode.getName());
							stringBuffer.append(" ");
							stringBuffer.append(true);
							stringBuffer.append(";");
							stringBuffer.append("\r\n");
							addressExsWriter.write(stringBuffer.toString());
						} catch (IOException ioe) {
							//skip the exception
						}

						return;
					}
					
					// append phone example
					matcher = phoneAnnotationPattern.matcher(innerText);
					if (matcher.find()) {

						innerText = innerText.trim();
						innerText = innerText.replaceAll("\\$phone", "");
						innerText = innerText.replaceAll("\\$/phone", "");

						boolean isPhonePattern = false;
						matcher = phonePattern.matcher(innerText);
						if (matcher.find()) {
							isPhonePattern = true;
						}

						try {
							stringBuffer.append(isPhonePattern);
							stringBuffer.append(" ");
							stringBuffer.append(domNode.getName());
							stringBuffer.append(" ");
							stringBuffer.append(true);
							stringBuffer.append(";");
							stringBuffer.append("\r\n");
							phoneExsWriter.write(stringBuffer.toString());
						} catch (IOException ioe) {
							//skip the exception
						}

						return;
					}
					
					// append all example
					try {
						stringBuffer.append(false);
						stringBuffer.append(" ");
						stringBuffer.append(domNode.getName());
						stringBuffer.append(" ");
						stringBuffer.append(false);
						stringBuffer.append(";");
						stringBuffer.append("\r\n");

						titleExsWriter.write(stringBuffer.toString());
						addressExsWriter.write(stringBuffer.toString());
						phoneExsWriter.write(stringBuffer.toString());
					} catch (IOException ioe) {
						//skip the exception
					}
				}
			});
			traversal.traverse();
		} finally {
			try {
				if (titleExsWriter != null) {
					titleExsWriter.close();
				}
			} catch (IOException ioe) {
				// skip the exception here
			}
			try {
				if (addressExsWriter != null) {
					addressExsWriter.close();
				}
			} catch (IOException ioe) {
				// skip the exception here
			}
			try {
				if (phoneExsWriter != null) {
					phoneExsWriter.close();
				}
			} catch (IOException ioe) {
				// skip the exception here
			}
		}
		
		
	}
}
